use anyhow::Result;
use bcrypt::{hash, verify, DEFAULT_COST};
use rand::Rng;

pub struct PasswordManager;

impl PasswordManager {
    pub fn hash_password(password: &str) -> Result<(String, String)> {
        let salt = Self::generate_salt();
        let combined = format!("{}{}", password, salt);
        
        match hash(&combined, DEFAULT_COST) {
            Ok(hash) => Ok((hash, salt)),
            Err(e) => Err(anyhow::anyhow!("Password hash failed: {}", e)),
        }
    }
    
    pub fn verify_password(password: &str, hash: &str, salt: &str) -> Result<bool> {
        let combined = format!("{}{}", password, salt);
        
        match verify(&combined, hash) {
            Ok(valid) => Ok(valid),
            Err(e) => Err(anyhow::anyhow!("Password verification failed: {}", e)),
        }
    }
    
    fn generate_salt() -> String {
        const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        let mut rng = rand::thread_rng();
        
        (0..32)
            .map(|_| {
                let idx = rng.gen_range(0..CHARSET.len());
                CHARSET[idx] as char
            })
            .collect()
    }
}
